import { TCpId } from "@/models/types";
import { computed, ref, Ref } from "vue";
import { IDataSource } from "./types";
import { iterFilterExpr } from "./utils";
import { TComponentServices } from "@/services/componentServices";

type TUpdateId = string

export function create(name: string, services: {
    component: TComponentServices
}): IDataSource {
    const update2FilterMap = new Map<TUpdateId, Ref<string>>()

    function toSqlWithFilters(requestorId: string, withOutFilters = false): Ref<string> {
        const sql = `select * from ${name}`

        if (withOutFilters) {
            return ref(sql)
        }

        return computed(() => {
            const filters = Array.from(iterFilterExpr(update2FilterMap, requestorId, [], services.component))
            const whereExpr = filters.map(v => v.value).join(' and ')

            if (whereExpr) {
                return `${sql} where ${whereExpr}`
            }

            return sql
        })
    }


    function addFilter(updateId: TUpdateId, expression: string): void {
        if (!update2FilterMap.has(updateId)) {
            throw new Error(`not found updateId[${updateId}]`);

        }
        update2FilterMap.get(updateId)!.value = expression
    }

    function removeFilters(updateId: TUpdateId): void {
        update2FilterMap.get(updateId)!.value = ''
    }

    function initFilter(updateId: TUpdateId) {
        update2FilterMap.set(updateId, ref(''))
    }

    function getAllFilters() {
        return Array.from(update2FilterMap.entries()).map(([id, filter]) => {

            return {
                id, filter
            }
        })
    }

    return {
        typeName: 'dataSource',
        name,
        toSqlWithFilters,
        addFilter,
        removeFilters,
        initFilter,
        getAllFilters,
    }

}